<template>
  <div class="app-container">
    <el-card class="box-card">
      <div slot="header" class="clearfix">
        <span>司机人脸识别</span>
      </div>

      <el-form
        ref="authForm"
        :model="form"
        :rules="rules"
        label-width="100px"
        class="mt-4"
      >
        <!-- 人脸照片 -->
        <el-form-item label="人脸照片">
          <div class="upload-container">
            <el-upload
              ref="upload"
              :action="uploadUrl"
              :before-upload="beforeUpload"
              :on-success="handleSuccess"
              :on-error="handleError"
              :show-file-list="false"
              accept="image/*"
              class="avatar-uploader"
            >
              <img v-if="imageUrl" :src="imageUrl" class="avatar" />
              <i v-else class="el-icon-plus avatar-uploader-icon"></i>
            </el-upload>

            <div class="upload-tips mt-2">
              <el-button type="primary" size="small" @click="handleCapture"
                >拍照</el-button
              >
              <span class="ml-2 text-gray"
                >或点击上传人脸照片，建议正面清晰照片</span
              >
            </div>
          </div>
        </el-form-item>

        <el-form-item>
          <el-button type="primary" @click="handleSubmit" :loading="loading"
            >开始识别</el-button
          >
          <el-button @click="handleReset">重置</el-button>
        </el-form-item>
      </el-form>
    </el-card>

    <!-- 人脸注册表单 -->
    <el-dialog
      title="注册新司机人脸信息"
      :visible.sync="showRegisterForm"
      width="400px"
    >
      <el-form
        ref="registerForm"
        :model="registerForm"
        :rules="registerRules"
        label-width="80px"
        class="mt-4"
      >
        <el-form-item label="司机ID" prop="driverId">
          <el-input
            v-model="registerForm.driverId"
            placeholder="请输入司机ID"
            clearable
          ></el-input>
        </el-form-item>
        <el-form-item label="司机姓名" prop="driverName">
          <el-input
            v-model="registerForm.driverName"
            placeholder="请输入司机姓名"
            clearable
          ></el-input>
        </el-form-item>
        <el-form-item>
          <el-button type="info" size="small" disabled>
            人脸照片已上传
          </el-button>
          <img v-if="imageUrl" :src="imageUrl" class="avatar" style="max-width: 100px; max-height: 100px;" />
        </el-form-item>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="showRegisterForm = false">取消</el-button>
        <el-button type="primary" @click="handleFaceRegister" :loading="registerLoading">确认注册</el-button>
      </div>
    </el-dialog>

    <!-- 认证结果弹窗 -->
    <el-dialog :title="resultTitle" :visible.sync="resultVisible" width="500px">
      <div class="result-container">
        <div v-if="resultSuccess" class="success-result">
          <i class="el-icon-success result-icon"></i>
          <p class="result-message">{{ resultMessage }}</p>
          <div v-if="authResult" class="result-details mt-4">
            <p><strong>检测结果：</strong>已检测到人脸</p>
            <p><strong>时间：</strong>{{ new Date().toLocaleString() }}</p>
          </div>
        </div>
        <div v-else class="error-result">
          <i class="el-icon-error result-icon"></i>
          <p class="result-message">{{ resultMessage }}</p>
        </div>
      </div>
      <div slot="footer" class="dialog-footer">
        <el-button @click="resultVisible = false">关闭</el-button>
      </div>
    </el-dialog>

    <!-- 相机弹窗 -->
    <el-dialog title="拍摄人脸照片" :visible.sync="cameraVisible" width="600px">
      <div class="camera-container">
        <video id="video" width="100%" height="auto" autoplay></video>
        <canvas
          id="canvas"
          width="600"
          height="450"
          style="display: none"
        ></canvas>
        <div class="camera-controls mt-4">
          <el-button type="primary" @click="takePhoto">拍照</el-button>
          <el-button @click="cameraVisible = false">取消</el-button>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import {
  recognize,
  faceDetect,
  getAuthToken,
  faceRegister
} from "@/api/driver/faceRecognition";

export default {
  name: "FaceRecognition",
  components: {},
  mixins: [],
  props: {},
  emits: [],
  data() {
    return {
      // 表单数据
      form: {
        faceImage: "",
      },
      // 表单验证规则
      rules: {
        faceImage: [
          {
            required: true,
            message: "请上传人脸照片",
            trigger: "change",
          },
        ],
      },
      // 上传相关
      uploadUrl: "", // 实际使用时会动态设置
      imageUrl: "",
      file: null,
      // 状态
      loading: false,
      // 结果弹窗
      resultVisible: false,
      resultTitle: "",
      resultSuccess: false,
      resultMessage: "",
      authResult: null,
      // 相机相关
      cameraVisible: false,
      videoStream: null,
      // 人脸注册相关
      showRegisterForm: false,
      registerForm: {
        driverId: '',
        driverName: '',
      },
      registerRules: {
        driverId: [
          {
            required: true,
            message: '请输入司机ID',
            trigger: 'blur',
          },
        ],
        driverName: [
          {
            required: true,
            message: '请输入司机姓名',
            trigger: 'blur',
          },
        ],
      },
      registerLoading: false,
    };
  },
  created() {
    // 初始化上传URL（实际上传时使用临时URL）
    this.uploadUrl = URL.createObjectURL(new Blob());
  },
  beforeDestroy() {
    // 释放相机资源
    if (this.videoStream) {
      this.videoStream.getTracks().forEach((track) => track.stop());
    }
  },
  methods: {
    // 表单提交处理
    handleSubmit() {
      this.$refs.authForm.validate((valid) => {
        if (valid) {
          this.loading = true;
          const formData = new FormData();
          formData.append("file", this.file);

          // 调用人脸识别接口
          recognize(formData)
            .then((response) => {
              this.loading = false;
              this.handleRecognitionResult(response);
            })
            .catch((error) => {
              this.loading = false;
              console.error("识别请求错误详情:", error);

              // 构建详细的错误信息
              let errorMessage = "网络异常或服务器错误，请稍后重试";
              let errorDetails = "";

              // 处理特定的错误类型
              if (error.code === "PERMISSION_DENIED") {
                errorMessage = error.message;
                if (error.details) {
                  errorDetails = `\n可能原因：${error.details.possibleReasons.join(
                    "、"
                  )}\n\n建议：${error.details.suggestion}`;
                }
              } else if (
                error &&
                error.response &&
                error.response.data &&
                error.response.data.msg
              ) {
                // 显示后端返回的错误信息
                errorMessage = error.response.data.msg;
              } else if (error.code === "NETWORK_ERROR") {
                errorMessage = error.message;
              } else if (error.code === "TIMEOUT_ERROR") {
                errorMessage = error.message;
              } else if (error.message) {
                errorMessage = error.message;
              }

              // 检查是否是"未找到匹配用户"的错误
              if (error.message && error.message.includes('match user is not found')) {
                // 显示确认对话框，询问是否注册新人脸
                this.$confirm('未找到匹配的司机信息，是否注册新的人脸信息？', '确认注册', {
                  confirmButtonText: '注册',
                  cancelButtonText: '取消',
                  type: 'warning'
                }).then(() => {
                  // 用户确认注册，打开司机信息表单
                  this.showRegisterForm = true;
                  this.loading = false;
                }).catch(() => {
                  // 用户取消注册
                  this.showResult("识别失败", false, "未找到匹配的司机信息");
                });
              } else {
                // 其他错误，直接显示错误信息
                this.showResult("识别失败", false, errorMessage + errorDetails);
              }
            });
        }
      });
    },

    // 处理识别结果
    handleRecognitionResult(response) {
      if (response && response.code === 200) {
        this.authResult = response.data;
        const userInfo = response.data.userInfo;

        if (userInfo) {
          let message = `识别成功，匹配到以下司机信息：\n`;
          message += `姓名：${userInfo.driverName}\n`;
          message += `手机号：${userInfo.driverPhone}\n`;
          message += `车牌号：${userInfo.licenseNumber}\n`;
          message += `匹配度：${userInfo.matchScore}%`;

          this.showResult("识别成功", true, message);
        } else {
          this.showResult("识别成功", true, "已检测到人脸，但未匹配到司机信息");
        }
      } else {
        this.showResult("识别失败", false, response.msg || "识别失败，请重试");
      }
    },

    // 显示结果弹窗
    showResult(title, success, message) {
      this.resultTitle = title;
      this.resultSuccess = success;
      this.resultMessage = message;
      this.resultVisible = true;
    },

    // 重置表单
    handleReset() {
      this.$refs.authForm.resetFields();
      this.imageUrl = "";
      this.file = null;
    },

    // 文件上传前校验
    beforeUpload(file) {
      const isImage = file.type.startsWith("image/");
      const isLt2M = file.size / 1024 / 1024 < 2;

      if (!isImage) {
        this.$message.error("上传文件必须是图片格式！");
        return false;
      }
      if (!isLt2M) {
        this.$message.error("上传图片大小不能超过2MB！");
        return false;
      }

      // 保存文件引用
      this.file = file;
      // 本地预览
      const reader = new FileReader();
      reader.onload = (e) => {
        this.imageUrl = e.target.result;
      };
      reader.readAsDataURL(file);

      // 阻止默认上传行为，使用自定义上传
      return false;
    },

    // 文件上传成功（由于阻止了默认上传，此方法不会被调用）
    handleSuccess() {
      // 预留
    },

    // 文件上传失败
    handleError() {
      this.$message.error("上传失败，请重试");
    },

    // 处理拍照功能
    handleCapture() {
      this.cameraVisible = true;
      // 使用nextTick确保DOM渲染完成后再初始化摄像头
      this.$nextTick(() => {
        this.initCamera();
      });
    },

    // 初始化相机
    initCamera() {
      const video = document.getElementById("video");
      if (!video) {
        this.$message.error("无法获取摄像头组件，请稍后重试");
        console.error("视频元素未找到");
        this.cameraVisible = false;
        return;
      }

      if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
        navigator.mediaDevices
          .getUserMedia({ video: true })
          .then((stream) => {
            this.videoStream = stream;
            video.srcObject = stream;
          })
          .catch((error) => {
            this.$message.error("无法访问摄像头，请确保您已授权");
            console.error("摄像头访问失败:", error);
            this.cameraVisible = false;
          });
      } else {
        this.$message.error("您的浏览器不支持摄像头功能");
        this.cameraVisible = false;
      }
    },

    // 拍照
    takePhoto() {
      const video = document.getElementById("video");
      const canvas = document.getElementById("canvas");

      if (!video || !canvas) {
        this.$message.error("无法获取摄像头组件，请稍后重试");
        console.error("视频或画布元素未找到");
        return;
      }

      const ctx = canvas.getContext("2d");

      // 绘制当前视频帧到canvas
      ctx.drawImage(video, 0, 0, canvas.width, canvas.height);

      // 将canvas内容转换为blob
      canvas.toBlob(
        (blob) => {
          // 创建一个文件对象
          this.file = new File([blob], "face.jpg", { type: "image/jpeg" });
          // 显示预览
          this.imageUrl = canvas.toDataURL("image/jpeg");

          // 释放相机资源
          if (this.videoStream) {
            this.videoStream.getTracks().forEach((track) => track.stop());
          }

          // 关闭相机弹窗
          this.cameraVisible = false;
        },
        "image/jpeg",
        0.8
      );
    },

    // 测试获取Token（调试用）
    testGetToken() {
      getAuthToken().then((response) => {
        console.log("百度云API Token:", response);
      });
    },
    
    // 处理人脸注册
    handleFaceRegister() {
      this.$refs.registerForm.validate((valid) => {
        if (valid && this.file) {
          this.registerLoading = true;
          const formData = new FormData();
          formData.append("file", this.file);
          formData.append("userId", this.registerForm.driverId);
          formData.append("userName", this.registerForm.driverName);

          // 调用人脸注册接口
          faceRegister(formData)
            .then((response) => {
              this.registerLoading = false;
              this.showRegisterForm = false;
              
              if (response && response.code === 200) {
                this.showResult(
                  "注册成功", 
                  true, 
                  `人脸注册成功！\n司机ID：${this.registerForm.driverId}\n司机姓名：${this.registerForm.driverName}`
                );
                // 清空注册表单
                this.$refs.registerForm.resetFields();
              } else {
                this.showResult("注册失败", false, response.msg || "人脸注册失败，请重试");
              }
            })
            .catch((error) => {
              this.registerLoading = false;
              console.error("人脸注册请求错误:", error);
              
              // 构建详细的错误信息
              let errorMessage = "网络异常或服务器错误，请稍后重试";
              if (error.response && error.response.data && error.response.data.msg) {
                errorMessage = error.response.data.msg;
              } else if (error.message) {
                errorMessage = error.message;
              }
              
              this.showResult("注册失败", false, errorMessage);
            });
        }
      });
    },
  },
};
</script>

<style scoped>
.upload-container {
  display: flex;
  flex-direction: column;
}

.avatar-uploader .el-upload {
  border: 1px dashed #d9d9d9;
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
}

.avatar-uploader .el-upload:hover {
  border-color: #409eff;
}

.avatar-uploader-icon {
  font-size: 28px;
  color: #8c939d;
  width: 200px;
  height: 200px;
  line-height: 200px;
  text-align: center;
}

.avatar {
  width: 200px;
  height: 200px;
  display: block;
}

.upload-tips {
  display: flex;
  align-items: center;
}

.text-gray {
  color: #606266;
}

.result-container {
  text-align: center;
  padding: 20px 0;
}

.result-icon {
  font-size: 48px;
  margin-bottom: 20px;
}

.success-result .result-icon {
  color: #67c23a;
}

.error-result .result-icon {
  color: #f56c6c;
}

.result-message {
  font-size: 16px;
  margin-bottom: 10px;
}

.result-details {
  text-align: left;
  background-color: #f5f7fa;
  padding: 15px;
  border-radius: 4px;
}

.camera-container {
  text-align: center;
}

.camera-controls {
  display: flex;
  justify-content: center;
  gap: 20px;
}
</style>
